# -*- coding: utf-8 -*-
# @Date：2024/10/1 02:08:40
# @Author：CJiaの青姝
# @FileName：details
# @Editor：PyCharm2024
# @Remark：
from typing import Any, List
from typing_extensions import Self

from application.models import AppDetails
from ninja import Router, Field, Query, ModelSchema

from utils.cj_ninja import CjFilters
from utils.cj_crud import create, delete, update, retrieve, single
from utils.cj_response import SuccessResponse, ErrorResponse

router = Router()


class Filters(CjFilters):
    appName: str = Field(None, description="应用名称", alias='appName')
    user_id: int = Field(None, description="所属用户id", alias='user_id')

    class Config:
        title = "应用详情查询参数"


class AppDetailsSchemaIn(ModelSchema):

    def validate(cls, value: Any) -> Self:
        if value.logo == '' or value.logo is None:
            return "logo地址不能为空", 400
        elif value.appName == '' or value.appName is None:
            return "应用名称不能为空", 400
        # 返回请求数据
        return value, 200

    def model_validate(
            cls,
            obj: Any,
            *,
            strict: bool | None = None,
            from_attributes: bool | None = None,
            context: Any | None = None,
    ) -> Self:
        if obj.logo == '' or obj.logo is None:
            return "logo地址不能为空", 400
        elif obj.appName == '' or obj.appName is None:
            return "应用名称不能为空", 400
        # 返回请求数据
        return obj.dict(), 200

    class Config:
        title = '创建应用详情参数'
        model = AppDetails
        model_exclude = ['id', 'creator', 'modifier', 'create_time', 'update_time',
                         'user', 'type', 'appVersion']


class AppDetailsSchemaOut(ModelSchema):
    class Config:
        title = '应用详情对象实例'
        model = AppDetails
        model_fields = "__all__"


@router.post("/details/add", response=AppDetailsSchemaOut, summary="创建应用详情")
def create_app_details(request: Any, data: AppDetailsSchemaIn) -> SuccessResponse | ErrorResponse:
    """ 创建应用详情 """
    message, code = data.model_validate(data)
    if code == 400:
        return ErrorResponse(msg=message)
    # 判断重复
    if AppDetails.objects.filter(appName=message['appName'], user_id=request.user_id).exists():
        return ErrorResponse(msg="应用名称已存在，请重新输入")
    # 补全参数
    message['user_id'] = request.user_id
    # 调用新增方法
    result = create(request, AppDetails, message)
    # 返回结果
    return SuccessResponse(data=result, msg="新增成功")


@router.delete("/details/del/{uuid}", response=AppDetailsSchemaOut, summary="删除应用详情")
def delete_app_details(request: Any, uuid: int) -> SuccessResponse | ErrorResponse:
    """ 删除应用详情 """
    # 调用删除方法
    result, code = delete(AppDetails, uuid)
    if code != 200:
        return ErrorResponse(code=code, msg=result)
    # 返回结果
    return SuccessResponse(data=result, msg="删除成功")


@router.put("/details/update/{uuid}", response=AppDetailsSchemaOut, summary="更新应用")
def update_app_details(request: Any, uuid: int, data: AppDetailsSchemaIn) -> SuccessResponse | ErrorResponse:
    """ 更新应用 """
    message, code = data.validate(data)
    if code == 400:
        return ErrorResponse(msg=message)
    # 判断重复
    if AppDetails.objects.filter(appName=message.appName, user_id=request.user_id).exclude(id=uuid).exists():
        return ErrorResponse(msg="应用名称已存在，请重新输入")
    # 调用修改方法
    result = update(request, AppDetails, message, uuid)
    # 返回结果
    return SuccessResponse(data=result, msg="更新成功")


@router.get("/details/listAll", response=List[AppDetailsSchemaOut], summary="获取应用详情所有列表")
def list_all_app_details(request: Any, filters: Filters = Query(...)) -> SuccessResponse | ErrorResponse:
    """ 获取应用详情所有列表 """
    # 取当前用户所属的应用
    filters.user_id = request.user_id
    # 调用列表通用方法
    result = retrieve(request, AppDetails, [], filters)
    # 返回结果
    return result


@router.get("/details/getById/{uuid}", response=AppDetailsSchemaOut, summary="获取应用详情")
def get_app_details(request: Any, uuid: int) -> SuccessResponse | ErrorResponse:
    """ 获取应用详情 """
    # 调用根据id获取指定对象方法
    result, code = single(request, AppDetails, [], uuid)
    if code != 200:
        return ErrorResponse(code=code, msg=result)
    # 返回结果
    return result
